/**

 这是一个用于失物招领应用的控制器类，它处理与物品相关的各种HTTP请求。
 该类使用Spring框架注解将HTTP请求映射到特定方法。
 */
package com.jsp.lostfound.controller;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import com.jsp.lostfound.entity.Goods;
import com.jsp.lostfound.service.AnswerUserService;
import com.jsp.lostfound.service.GoodsService;
import net.sf.json.JSONObject;

@Controller
public class GoodsController {

	@Autowired
	private GoodsService goodsService;
	@Autowired
	private AnswerUserService answerUserService;

	/**
	 * 设置正在展示的物品信息的类型。
	 *
	 * @param infoType 物品信息类型
	 * @param url      视图名称
	 * @return 包含物品信息类型的ModelAndView对象
	 */
	@RequestMapping("/setGoodsInfoType")
	public ModelAndView setGoodsInfoType(String infoType, String url) {
		ModelAndView modelAndView = new ModelAndView(url);
		modelAndView.addObject("infoType", infoType);
		return modelAndView;
	}

	/**
	 * 发布新物品。
	 *
	 * @param goods 物品对象
	 * @return 跳转到home.jsp的视图名称
	 */
	@RequestMapping("/publishGoods")
	public String publishGoods(Goods goods) {
		//获取当前距1970年的相隔秒
		Date tasktime = new Date(System.currentTimeMillis());
		// 设置日期输出的格式
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		goods.setPublishTime(df.format(tasktime));
		goodsService.addGoods(goods);
		return "forward:home.jsp";
	}

	/**
	 * 上传文件。
	 *
	 * @param req        HTTP请求对象
	 * @param uploadFile 文件对象
	 * @param flag       标志位
	 * @return 文件名的JSON字符串
	 * @throws JsonProcessingException
	 */
	@RequestMapping("/uploadFile")
	@ResponseBody
	public String uploadFile(HttpServletRequest req, MultipartFile uploadFile, Integer flag) throws JsonProcessingException {
		if (uploadFile == null || uploadFile.isEmpty()) {
			return "上传文件为空";
		}

		String originalFilename = uploadFile.getOriginalFilename();
		String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));

		String uploadDirPath;
		if (flag == null) {
			// 上传商品图片
			uploadDirPath = "E:\\Exercise\\project\\jsp-master-lam\\src\\main\\webapp\\resources\\upload_goods_pic";
		} else {
			// 上传其他文件
			uploadDirPath = "E:\\Exercise\\project\\jsp-master-lam\\src\\main\\webapp\\resources\\upload_files";
		}

		// 检查上传路径是否存在，不存在则创建
		File uploadDir = new File(uploadDirPath);
		if (!uploadDir.exists()) {
			uploadDir.mkdirs();
		}

		// 将上传的文件保存到指定的位置
		try (InputStream in = uploadFile.getInputStream();
			 OutputStream out = new FileOutputStream(new File(uploadDir, newFileName))) {
			byte[] buffer = new byte[1024];
			int length;
			while ((length = in.read(buffer)) > 0) {
				out.write(buffer, 0, length);
			}
		} catch (IOException e) {
			e.printStackTrace();
			return "上传失败";
		}

		// return "{\"status\": \"success\", \"fileName\": \"" + newFileName + "\"}";		// 将上传的文件名转换为 JSON 格式并返回
		return new ObjectMapper().writeValueAsString(newFileName);
	}

	/**
	 * 搜索物品标题。
	 *
	 * @param title 物品标题
	 * @param state 物品状态
	 * @return 包含搜索标题和状态的ModelAndView对象
	 */
	@RequestMapping("/searchGoodsTitle")
	public ModelAndView searchGoodsTitle(String title, String state) {
		ModelAndView modelAndView = new ModelAndView("searchGoodsTitle");
		modelAndView.addObject("title", title);
		modelAndView.addObject("state", state);
		return modelAndView;
	}

	/**
	 * 获取搜索结果的数量。
	 *
	 * @param conditions 搜索条件
	 * @return 搜索结果数量的字符串形式
	 */
	@RequestMapping("/getSearchNums")
	@ResponseBody
	public String getSearchNums(Goods conditions) {
		//对象无法接受json的格式,只能接受&连接起来的string username=ax&password=123 这种
		return String.valueOf(goodsService.searchGoodsNums(conditions));
	}

	/**
	 * 加载搜索结果数据。
	 *
	 * @param pageNum    当前页号
	 * @param pageSize   页面大小
	 * @param conditions 搜索条件
	 * @return 包含搜索结果的List
	 */
	@RequestMapping("/loadSearchData")
	@ResponseBody
	public List<Goods> loadSearchData(@RequestParam(required = true) int pageNum,
									  @RequestParam(required = true) int pageSize, String conditions) {
		//将conditions json字符串转化为json对象
		JSONObject json = JSONObject.fromObject(conditions);
		//将json对象转化为java对象,这里java对象中必须要有无参的构造方法才行,要不会报net.sf.json.JSONException: java.lang.NoSuchMethodException: init
		//这里ObjectMapper也可以转化
		Goods goods = (Goods) JSONObject.toBean(json, Goods.class);
		List<Goods> list = goodsService.searchGoodsInfo(pageNum, pageSize, goods);
		return list;
	}

	/**
	 * 显示物品详情。
	 *
	 * @param id       物品ID
	 * @param infoType 物品类型
	 * @return 包含物品详情和类型的ModelAndView对象
	 */
	@RequestMapping("/showGoodsDetail")
	public ModelAndView showGoodsDetail(Integer id, String infoType) {
		ModelAndView modelAndView = new ModelAndView("goodsDetail");
		Goods lostGoods = goodsService.showGoodsDetail(id);
		modelAndView.addObject("goods", lostGoods);
		modelAndView.addObject("infoType", infoType);
		return modelAndView;
	}

	/**
	 * 更改物品状态。
	 *
	 * @param state 物品状态
	 * @param id    物品ID
	 * @param auid  用户ID
	 * @param out   输出流对象
	 */
	@RequestMapping("/changeGoodsState")
	public void changeGoodsState(Integer state, Integer id, Integer auid, PrintWriter out) {
		goodsService.changeGoodsState(state, id, auid);
		out.write("物品状态已改变");
	}

	/**
	 * 获取物品数量。
	 *
	 * @param infoType 物品类型
	 * @param state    物品状态
	 * @return 物品数量的字符串形式
	 */
	@RequestMapping("/getGoodsNums")
	@ResponseBody
	public String getGoodsNums(String infoType, Integer state) {
		return String.valueOf(goodsService.showGoodsNums(infoType, state));
	}

	/**
	 * 加载物品数据。
	 *
	 * @param pageNum  当前页号
	 * @param pageSize 页面大小
	 * @param infoType 物品类型
	 * @param state    物品状态
	 * @return 包含物品数据的List
	 */

	@RequestMapping("/loadGoodsData")
	@ResponseBody
	public List<Goods> loadGoodsData(@RequestParam(required = true) int pageNum,
									 @RequestParam(required = true) int pageSize, String infoType, Integer state) {
		return goodsService.showGoodsInfo(pageNum, pageSize, infoType, state);
	}


	/**
	 * 从数据库中删除指定ID的物品。
	 *
	 * @param id  待删除物品的ID
	 * @param out 用于输出删除结果的PrintWriter对象
	 */
	@RequestMapping("/removeGoods")
	public void removeGoods(Integer id, PrintWriter out) {
		goodsService.removeGoods(id);
		out.write("删除成功");
	}

	/**
	 * 获取某个用户已完成的指定类型物品的信息数量。
	 *
	 * @param infoType 物品类型
	 * @param username 用户名
	 * @return 用户已完成的指定类型物品的信息数量
	 */
	@RequestMapping("/getFinishedGoodsNums")
	@ResponseBody
	public String getFinishedGoodsNums(String infoType, String username) {
		List<Integer> list = answerUserService.showAuIdByUsername(username);
		if (list.size() == 0)
			return "0";// 如果list里什么都没有 即list=[]则不进行select from where id in list的查找会出错
		return String.valueOf(goodsService.showFinishedGoodsNums(infoType, list));
	}

	/**
	 * 分页加载某个用户已完成的指定类型物品的信息。
	 *
	 * @param pageNum  当前页码
	 * @param pageSize 每页信息数量
	 * @param infoType 物品类型
	 * @param username 用户名
	 * @return 分页加载的物品信息列表
	 */
	@RequestMapping("/loadFinishedGoodsData")
	@ResponseBody
	public List<Goods> loadFinishedGoodsData(@RequestParam(required = true) int pageNum,
											 @RequestParam(required = true) int pageSize, String infoType, String username) {
		List<Integer> list = answerUserService.showAuIdByUsername(username);
		return goodsService.showFinishedGoodsInfo(pageNum, pageSize, infoType, list);
	}
}